package com.xlh.service.user.impl;

import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Table;
import com.xlh.constant.UserConstant;
import com.xlh.dao.user.ClassCourseMapper;
import com.xlh.dao.user.ClassMapper;
import com.xlh.dao.user.UserExtendMapper;
import com.xlh.dao.user.UserMapper;
import com.xlh.dao.user.ext.ClassCourseMapperExt;
import com.xlh.dao.user.ext.ClassMapperExt;
import com.xlh.dao.user.ext.UserMapperExt;
import com.xlh.dto.PageDTO;
import com.xlh.dto.course.ChapterBasicInfoDTO;
import com.xlh.dto.course.ClassZtreeDTO;
import com.xlh.dto.course.CourseDTO;
import com.xlh.dto.system.ResourceRelationDTO;
import com.xlh.dto.user.*;
import com.xlh.enums.ResourceRelationTypeEnum;
import com.xlh.enums.ResourcesTypeEnum;
import com.xlh.enums.course.ChapterEnum;
import com.xlh.enums.user.ClassStatusEnum;
import com.xlh.enums.user.IdentityEnum;
import com.xlh.enums.user.UserStatusEnum;
import com.xlh.exception.DeleteDealOperatingException;
import com.xlh.exception.common.BadRequestException;
import com.xlh.exception.common.GlobalException;
import com.xlh.exception.common.NotFoundException;
import com.xlh.param.course.ClassCourseParam;
import com.xlh.param.course.CreateChapterCourseSortParam;
import com.xlh.param.course.CreateOrUpdateCourseSortParam;
import com.xlh.param.user.CreateUserParam;
import com.xlh.param.user.UpdateClassParam;
import com.xlh.pojo.course.ChapterCourseSort;
import com.xlh.pojo.course.CourseSort;
import com.xlh.pojo.course.CourseTeacher;
import com.xlh.pojo.system.ResourceRelation;
import com.xlh.pojo.user.Class;
import com.xlh.pojo.user.*;
import com.xlh.security.UserInfoHolder;
import com.xlh.service.course.ChapterService;
import com.xlh.service.course.CourseService;
import com.xlh.service.course.DirectionService;
import com.xlh.service.courseTest.PaperService;
import com.xlh.service.courseTest.QuestionRepositoryService;
import com.xlh.service.system.SystemResourceService;
import com.xlh.service.user.ClassService;
import com.xlh.service.user.UserService;
import com.xlh.support.attendance.service.AttendanceService;
import com.xlh.util.BeanUtil;
import com.xlh.util.InputValidator;
import com.xlh.virtualization.constant.ContextTypeEnum;
import com.xlh.virtualization.service.ContainerService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 班级
 * <p>
 * Created by lx on 2019/1/28.
 */
@Service
public class ClassServiceImpl implements ClassService {

    private static Table<Long, Long, Class> defaultClassMap = HashBasedTable.create();

    @Autowired
    private ClassCourseMapperExt classCourseMapperExt;

    @Autowired
    private UserMapperExt userMapperExt;

    @Autowired
    private ClassMapper classMapper;

    @Autowired
    private ClassMapperExt classMapperExt;

    @Autowired
    private ClassCourseMapper classCourseMapper;

    @Autowired
    private UserInfoHolder userInfoHolder;

    @Autowired
    private UserService userService;

    @Autowired
    private CourseService courseService;

    @Autowired
    private ChapterService chapterService;

    @Autowired
    private ClassService classService;

    @Autowired
    private PaperService paperService;

    @Autowired
    private QuestionRepositoryService questionRepositoryService;

    @Autowired
    private AttendanceService attendanceService;

    @Autowired
    private UserServiceImpl userserviceimpl;

    @Autowired
    private ContainerService containerService;

    @Autowired
    private SystemResourceService resourceService;

    @Autowired
    private DirectionService directionService;

    @Override
    public List<ClassDTO> listClassCourse(Long courseId, Long userId, String grade, Boolean endFlag, String name) {

        // 获取课程的主讲id
        Long speakerId = courseService.getCourseById(courseId).getUserId();

        // 获取课程的辅助教师的信息
        List<CourseTeacher> courseTeachers = courseService.queryCourseTeacher(
                Lists.newArrayList(courseId), userId, null);
        List<Long> assistantIds = courseTeachers.stream().map(CourseTeacher::getUserId).collect(Collectors.toList());

        // 获取数据，如果为空，则返回空。
        List<ClassDTO> classDTOS = getClassList(courseId, null, grade, name);
        if ((userId != null && !Objects.equals(speakerId, userId) && !assistantIds.contains(userId))
                || CollectionUtils.isEmpty(classDTOS)) {
            return null;
        }

        if (endFlag != null) {
            classDTOS = classDTOS.stream()
                    .filter(classDTO -> Objects.equals(classDTO.getEnded(), endFlag))
                    .collect(Collectors.toList());
        }
        if (CollectionUtils.isEmpty(classDTOS)) return Lists.newArrayList();

        // 如果这门课程是助教教师教授的话，需要过滤课程id
        if (CollectionUtils.isNotEmpty(courseTeachers) && userId != null && !Objects.equals(speakerId, userId)) {
            List<Long> classIds = courseTeachers.stream().map(CourseTeacher::getClassId).collect(Collectors.toList());
            classDTOS = classDTOS.stream()
                    .filter(classDTO -> classIds.contains(classDTO.getId())).collect(Collectors.toList());
        }

        // 获取默认班级
        Class defaultInfo = getDefaultClass(courseId);
        if (defaultInfo != null) {
            classDTOS.forEach(classDTO -> {
                if (Objects.equals(defaultInfo.getId(), classDTO.getId())) {
                    classDTO.setDefaultedClass(true);
                }
            });
        }

        // 排序
        classDTOS.sort(Comparator.comparing(ClassDTO::getDefaultedClass).reversed());
        return classDTOS;
    }

    @Override
    public List<ClassDTO> listClassCourse(Long courseId, String grade, Boolean endFlag, String name) {
        List<ClassDTO> classDTOS = listClassCourse(courseId, userInfoHolder.getUserId(), grade, endFlag, name);
        if (CollectionUtils.isEmpty(classDTOS)) {
            throw new NotFoundException("");
        }
        return classDTOS;
    }

    @Override
    public List<ClassZtreeDTO> queryClassCourse(Long courseId, Boolean allFlag, Boolean defaultClassFlag) {
        // 获取该课程下所有的班级
        List<ClassDTO> classDTOS = listClassCourse(courseId, userInfoHolder.getUserId(), null, null, null);
        // 转换数据
        return convertZtreeDTO(classDTOS, allFlag, defaultClassFlag);
    }

    @Override
    public void updateDefaultClass(Long courseId, Long classId) {
        Class classInfo = classMapper.selectByPrimaryKey(classId);
        if (classInfo == null || classInfo.getDeleted()) {
            throw new GlobalException("当前班级已结课或不存在");
        }
        // 查询 当前班级 是否是 这个教师去教
        List<ClassDTO> classDTOS = getClassList(courseId, false, null, null);
        if (CollectionUtils.isEmpty(classDTOS)) {
            throw new GlobalException("当前班级不在当前课程中");
        }
        if (classDTOS.stream()
                .filter(classDTO -> Objects.equals(classDTO.getId(), classId))
                .count() == 0) {
            throw new GlobalException("当前班级不在当前课程中");
        }
        defaultClassMap.put(courseId, userInfoHolder.getUserId(), classInfo);
    }

    @Override
    public Class getDefaultClass(Long courseId) {
        return getDefaultClass(courseId, userInfoHolder.getUserId());
    }

    @Override
    public Class getDefaultClass(Long courseId, Long userId) {
        if (defaultClassMap.contains(courseId, userId)) {
            return defaultClassMap.get(courseId, userId);
        }

        // map值没有，则去数据库查询，如果数据库为空，则给空
        List<ClassDTO> classDTOS = getClassList(courseId, false, null, null);
        if (CollectionUtils.isEmpty(classDTOS)) return null;

        // 获取班级信息
        Class classInfo = queryClass(classDTOS.get(0).getId());

        // 往map里面放值
        defaultClassMap.put(courseId, userId, classInfo);

        // 从map里面取值
        return defaultClassMap.get(courseId, userId);
    }

    @Override
    public void deleteDefaultClass(Long courseId, Long classId) {

        // 查看默认班级集合的列和值
        Map<Long, Class> rowMap = defaultClassMap.row(courseId);
        List<Long> userIds = Lists.newArrayList(rowMap.keySet());

        List<Long> courseUserIds = getCourseUserIds(courseId);
        if (CollectionUtils.isNotEmpty(courseUserIds)) {
            userIds = courseUserIds;
        }

        // 删除缓存中的值
        userIds.forEach(userId -> {
            Class defaultClassInfo = defaultClassMap.get(courseId, userId);
            if (defaultClassInfo != null && Objects.equals(defaultClassInfo.getId(), classId)) {
                defaultClassMap.remove(courseId, userId);
            }
        });
    }

    private List<Long> getCourseUserIds(Long courseId) {
        // 查询课程的教师
        List<CourseDTO> courseDTOS = courseService.queryCourses(null, courseId);
        if (CollectionUtils.isEmpty(courseDTOS)) return Lists.newArrayList();

        CourseDTO courseDTO = courseDTOS.get(0);
        List<Long> userIds = Lists.newArrayList(courseDTO.getUserId());
        userIds.addAll(courseDTO.getUserIds());
        return userIds.stream().distinct().collect(Collectors.toList());
    }

    @Override
    public Class queryClass(Long classId) {
        return classMapper.selectByPrimaryKey(classId);
    }

    @Override
    public List<ClassCourseDTO> listClassCourse(List<Long> courseIds, Boolean endFlag) {
        return classCourseMapperExt.listClassCourse(courseIds, endFlag, null, null, null);
    }

    @Override
    public PageDTO<ClassInfoDTO> listClassByPage(Integer pageNum, Integer pageSize,
                                                 Long courseId, Boolean endFlag, String grade) {

        // 获取当前教师这门课的班级id集合
        List<Long> classIds = getCourseTeacherClassId(courseId, userInfoHolder.getUserId(), endFlag);
        //判断如否可以添加班级
        List<UserInfoDTO> courseTeachers = courseService.getCourseTeachers(courseId, null);
        PageHelper.startPage(pageNum, pageSize);
        List<ClassCourseDTO> classes = classCourseMapperExt.listClassCourse(
                Lists.newArrayList(courseId), endFlag, grade, null, classIds);
        PageInfo pageInfo = new PageInfo<>(classes);
        pageInfo.setList(convertClass(pageInfo.getList()));

        return new PageDTO<>(pageInfo);
    }

    @Override
    public List<Class> getTeacherClass(Long userId, Boolean endFlag) {
        List<Long> classIds = getTeacherClassId(userId, endFlag);
        if (CollectionUtils.isEmpty(classIds)) return Lists.newArrayList();
        return listClass(classIds, false);
    }

    @Override
    public List<Long> getTeacherClassId(Long userId, Boolean endFlag) {
        // 获取自己是主讲教师创建的班级
        List<ClassCourse> classCourses = listTeacherClass(userId, endFlag, null, null);
        List<Long> classIds = classCourses.stream().map(ClassCourse::getClassId).collect(Collectors.toList());

        // 获取自己是助教教师创建的班级
        List<CourseTeacher> courseTeachers = courseService.queryCourseTeacher(null, userId, null);
        List<Long> assistantClassIds = courseTeachers.stream()
                .map(CourseTeacher::getClassId).collect(Collectors.toList());

        // 合并
        classIds.addAll(assistantClassIds);

        return classIds.stream().distinct().collect(Collectors.toList());
    }

    private List<Long> getCourseTeacherClassId(Long courseId, Long userId, Boolean endFlag) {

        // 获取课程的主讲id
        Long speakerId = courseService.getCourseById(courseId).getUserId();

        // 获取主讲教师的班级id
        List<ClassCourse> classCourses = listTeacherClass(speakerId, endFlag, null, courseId);

        if (Objects.equals(speakerId, userId)) {
            return classCourses.stream().map(ClassCourse::getClassId).collect(Collectors.toList());
        }

        // 获取助教的班级id
        List<CourseTeacher> courseTeachers = courseService.queryCourseTeacher(
                Lists.newArrayList(courseId), userId, null);
        List<Long> assistantClassIds = courseTeachers.stream()
                .map(CourseTeacher::getClassId).collect(Collectors.toList());

        return classCourses.stream()
                .filter(classCourse -> assistantClassIds.contains(classCourse.getClassId()))
                .map(ClassCourse::getClassId).collect(Collectors.toList());
    }

    @Override
    public List<ClassCourse> listTeacherClass(Long userId, Boolean endFlag, Long classId, Long courseId) {
        return classCourseMapperExt.listTeacherClass(endFlag, userId, courseId, classId);
    }

    @Override
    public List<CourseClassDTO> queryUserClass(List<Long> courseIds) {
        return classCourseMapperExt.queryUserClass(courseIds);
    }

    @Override
    public List<Class> listClass(List<Long> classIds, Boolean deleted) {
        ClassExample example = new ClassExample();
        ClassExample.Criteria criteria = example.createCriteria();
        if (CollectionUtils.isNotEmpty(classIds)) {
            criteria.andIdIn(classIds);
        }
        if (deleted != null) {
            criteria.andDeletedEqualTo(deleted);
        }
        return classMapper.selectByExample(example);
    }

    @Override
    public List<ClassCourse> listClassCourse(Long courseId, Boolean deleted) {
        ClassCourseExample example = new ClassCourseExample();
        ClassCourseExample.Criteria criteria = example.createCriteria();
        criteria.andCourseIdEqualTo(courseId);
        if (deleted != null) {
            criteria.andDeletedEqualTo(false);
        }
        return classCourseMapper.selectByExample(example);
    }

    @Override
    public List<UserClassDTO> queryHistoryClass(String classInfo, Long userId) {
        List<UserClassDTO> userClassDTOS = userService.queryHistoryClass(classInfo, userId);
        return convertUserClass(userClassDTOS);
    }

    @Override
    public List<UserClassDTO> queryHistoryClass(String classInfo, Long userId, String falg) {
        List<UserClassDTO> userClassDTOS = userService.queryHistoryClass(classInfo, userId);
        return userClassDTOS;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createClass(Long courseId, List<CreateUserParam> createUserParams,
                            Long studentClassId, String name, Integer grade, Boolean errorFlag, Long userId, List<Long> studentIds) {

        List<CourseDTO> courseInfos = courseService.getCourseInfo(Lists.newArrayList(courseId));
        if (CollectionUtils.isEmpty(courseInfos)) {
            throw new BadRequestException("当前课程不存在");
        }
        if(StrUtil.isNotBlank(name)){
            name = InputValidator.regSpecialChar(name);
        }
        // 检查参数 并 获取学生的id
        List<Long> userIds = checkAndGetUserIds(Lists.newArrayList(courseId), name, grade,
                studentClassId, createUserParams, errorFlag, userId, studentIds);

        // 转换班级数据并插入数据库
        Class dbClass = convertClass(name, grade, userId);
        classMapper.insertSelective(dbClass);

        // 往user_class添加数据
        createUserClass(dbClass.getId(), userIds);

        // 往class_course添加数据
        List<Long> newClassIds = createCourseClass(courseInfos, dbClass.getId(), userId);

        return newClassIds.get(0);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createClass(Long courseId, Long studentClassId, Boolean errorFlag, Long userId) {
        // 检查课程
        List<CourseDTO> courseInfos = courseService.getCourseInfo(Lists.newArrayList(courseId));
        if (CollectionUtils.isEmpty(courseInfos)) {
            throw new BadRequestException("当前课程不存在");
        }

//        List<ClassCourseDTO> classCourseDTOS = listClassCourse(Lists.newArrayList(courseId), null);
//        if (classCourseDTOS.stream()
//                .filter(classCourseDTO -> Objects.equals(studentClassId, classCourseDTO.getId())).count() > 0) {
//            throw new GlobalException("当前班级已存在，不能重复添加");
//        }
        List<String> userid = classCourseMapperExt.listClassCourseOther(courseId, studentClassId);
        if (userid.size() > 0) throw new GlobalException("教师" + userid.get(0).toString() + "已将此班级添加到当前课程中，不能重复添加");

        //过滤虚拟班级里的学生
        List<UserInfoDTO> userInfoDTOS = userService.queryClassUser(Lists.newArrayList(studentClassId), null);
        List<CreateUserParam> params = Lists.newArrayList();
        for (UserInfoDTO userInfoDTO : userInfoDTOS) {
            CreateUserParam createUserParam = new CreateUserParam();
            createUserParam.setId(userInfoDTO.getId());
            createUserParam.setPassword(userInfoDTO.getPassword());
            createUserParam.setUserNumber(userInfoDTO.getUserNumber());
            createUserParam.setApplicant(userInfoDTO.getApplicant());
            createUserParam.setCourseDirectionHideIds(userInfoDTO.getCourseDirectionHideIds());
            createUserParam.setEmail(userInfoDTO.getEmail());
            createUserParam.setName(userInfoDTO.getName());
            createUserParam.setRole(userInfoDTO.getRole());
            createUserParam.setSex(userInfoDTO.getSex());
            params.add(createUserParam);
        }
        userserviceimpl.checkAndFilterUserNumber(params, Lists.newArrayList(courseId), studentClassId, errorFlag);

        // 检查参数 并 获取学生的id
        checkAndGetUserId(Lists.newArrayList(courseId), studentClassId, null, errorFlag, null);

        // 往class_course添加数据
        List<Long> newCourseIds = createCourseClass(courseInfos, studentClassId, userId);

        return newCourseIds.get(0);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createClass(Class classObj, List<CreateUserParam> userParams) {

        // 检查班级信息
        checkClass(classObj.getName(), Integer.valueOf(classObj.getGrade()), classObj.getUserId());

        // 插入数据库
        classMapper.insertSelective(classObj);

        return classObj.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createClassUser(List<Long> courseIds, List<CreateUserParam> createUserParams,
                                Long studentClassId, Boolean errorFlag, Long userId) {

        List<CourseDTO> courseInfos = courseService.getCourseInfo(courseIds);
        if (CollectionUtils.isEmpty(courseInfos)) {
            throw new BadRequestException("当前课程不存在");
        }

        // 检查参数 并 获取学生的id
        List<Long> userIds = checkAndGetUserId(courseIds, studentClassId, createUserParams, errorFlag, null);

        // 往user_class添加数据
        createUserClass(studentClassId, userIds);

        // 往class_course添加数据
        createCourseClass(courseInfos, studentClassId, userId);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<Long> createCourseClass(List<CourseDTO> courseInfos, Long studentClassId, Long userId) {

        // 拷贝课程
        List<Long> newCourseIds = copyCourse(courseInfos, userId);

        // 往class_course 表进行操作
        insertClassCourse(studentClassId, newCourseIds);
        List<CourseTeacher> list = Lists.newArrayList();
        List<UserInfoDTO> userInfoDTOS = userMapperExt.listUserOtherTeacher(
                courseInfos.get(0).getId(), null,
                UserStatusEnum.NOT_DELETE.getCode(), userInfoHolder.getUserId());
        if (CollectionUtils.isNotEmpty(userInfoDTOS)) {
            for (UserInfoDTO userInfoDTO : userInfoDTOS) {
                CourseTeacher courseTeacher = new CourseTeacher();
                courseTeacher.setUserId(userInfoDTO.getId());
                courseTeacher.setCourseId(courseInfos.get(0).getId());
                courseTeacher.setClassId(studentClassId);
                courseTeacher.setCreateTime(new Date());
                list.add(courseTeacher);
            }
            userMapperExt.saveCourseTeacher(list);
        }

        return newCourseIds;

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createUserClass(Long classId, List<Long> userIds) {
        if (CollectionUtils.isEmpty(userIds)) return;
        userService.insertBatchUserClass(userIds, classId);
    }

    @Override
    public void updateNaturalClass(Long courseId, Long classId, UpdateClassParam updateClassParam) {

        Class dbClass = checkAndGetClass(classId, updateClassParam.getName());

        Class updateClass = BeanUtil.transform(Class.class, updateClassParam);
        updateClass.setId(classId);
        updateClass.setUpdateTime(new Date());
        classMapper.updateByPrimaryKeySelective(updateClass);

        Class newClassInfo = classMapper.selectByPrimaryKey(dbClass.getId());

        // 修改默认班级
        updateDefaultClass(dbClass, newClassInfo);
    }

    @Override
    public void updateClass(Long courseId, Long classId, UpdateClassParam updateClassParam) {

        Class dbClass = checkAndGetClass(classId, updateClassParam.getName());

        Class updateClass = BeanUtil.transform(Class.class, updateClassParam);
        updateClass.setId(classId);
        classMapper.updateByPrimaryKeySelective(updateClass);

        Class newClassInfo = classMapper.selectByPrimaryKey(dbClass.getId());

        // 修改默认班级
        updateDefaultClass(dbClass, newClassInfo);
    }

    private void updateDefaultClass(Class oldClassInfo, Class newClassInfo) {
        defaultClassMap.cellSet().forEach(data -> {
            if (Objects.equals(oldClassInfo.getId(), data.getValue().getId())) {
                defaultClassMap.put(data.getRowKey(), data.getColumnKey(), newClassInfo);
            }
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatchClass(Long courseId, List<Long> classIds, Boolean errorFlag, Boolean logicDeleted) {

        /**
         * 删除内容：
         * 1. 关闭签到
         * 2. 删除班级、班级下的学生、班级学生的关联关系
         * 3. 与‘删除学生’逻辑一致
         * 4. 删除试卷与班级的关联关系
         * 5. 解除助教的关联关系
         */
        classIds = checkAndGetClassIds(courseId, classIds, errorFlag);
        if (CollectionUtils.isEmpty(classIds)) return;

        // 关闭签到
        for (Long classId : classIds) {
            List<Long> teacherIds = courseService.getCourseTeacherIds(courseId, classId);
            if (CollectionUtils.isNotEmpty(teacherIds)) {
                for (Long teacherId : teacherIds) {
                    attendanceService.endRecord(teacherId, courseId, Lists.newArrayList(classId));
                }
            }
        }

        // 将自然班级进行过滤
        List<Class> dbClass = queryClassByIds(classIds);
        List<Long> teacherClassIds = dbClass.stream()
                .filter(classInfo -> classInfo.getUserId() != null).map(Class::getId).collect(Collectors.toList());
        if (teacherClassIds != null && teacherClassIds.size() > 0) {

            // 删除学生
            teacherClassIds.forEach(classId -> {
                List<UserInfoDTO> userInfoDTOS = userService.queryClassUser(null, Lists.newArrayList(classId),
                        Lists.newArrayList(UserStatusEnum.NOT_DELETE.getCode(),
                                UserStatusEnum.ACCOUNT_CANCELLATION.getCode()), false);
                if (CollectionUtils.isNotEmpty(userInfoDTOS)) {
                    userService.batchDeleteUser(courseId, classId,
                            userInfoDTOS.stream().map(UserInfoDTO::getId).collect(Collectors.toList()),
                            logicDeleted, errorFlag, null);
                }
            });

            // 批量删除用户和班级的关联关系
            userService.batchDeleteUserClass(teacherClassIds, null, logicDeleted);

            // 批量删除班级
            deleteClass(teacherClassIds, logicDeleted);
        }
        teacherClassIds = dbClass.stream()
                .filter(classInfo -> classInfo.getId() != null).map(Class::getId).collect(Collectors.toList());
        teacherClassIds.forEach(classIdna -> {
            List<UserInfoDTO> userInfoDTOS = userService.queryClassUser(null, Lists.newArrayList(classIdna),
                    Lists.newArrayList(UserStatusEnum.NOT_DELETE.getCode(),
                            UserStatusEnum.ACCOUNT_CANCELLATION.getCode()), false);
            if (CollectionUtils.isNotEmpty(userInfoDTOS)) {
                List<Long> userids = userInfoDTOS.stream().map(UserInfoDTO::getId).collect(Collectors.toList());
                userserviceimpl.deleteStudentId(userids, courseId, classIdna);
            }
        });

        // 批量删除班级和课程的关联关系
        deleteClassCourse(courseId, classIds, logicDeleted);

        // 删除默认班级
        classIds.forEach(classId -> deleteDefaultClass(courseId, classId));

        // 删除试卷
        paperService.deletePaper(courseId, classIds);

        // 解除助教的关联关系
        courseService.deleteCourseTeachers(courseId, classIds);

    }


    @Override
    public void deleteNaturalBatchClass(List<Long> classIds, Boolean errorFlag, Boolean logicDeleted) {
        int count = classMapper.selectClassCourse(classIds);
        if (count > 0) {
            throw new GlobalException("删除班级存在关联关系请联系管理员");
        }
        classIds.forEach(classId -> {
            List<UserInfoDTO> userInfoDTOS = userService.queryClassUser(null, Lists.newArrayList(classId),
                    Lists.newArrayList(UserStatusEnum.NOT_DELETE.getCode(),
                            UserStatusEnum.ACCOUNT_CANCELLATION.getCode()), false);
            if (CollectionUtils.isNotEmpty(userInfoDTOS)) {
                userService.batchNaDeleteUser(null, classId,
                        userInfoDTOS.stream().map(UserInfoDTO::getId).collect(Collectors.toList()),
                        logicDeleted, errorFlag);
            }
        });
        // 批量删除班级
        deleteClass(classIds, logicDeleted);

        // 批量删除用户和班级的关联关系
        userService.batchDeleteUserClass(classIds, null, logicDeleted);
    }

    @Override
    public void endClass(Long courseId, Long classId, Boolean errorFlag) {

        /**
         * 结课逻辑：
         * 1. 关闭签到
         * 2. 改变课程与班级的状态
         * 3. 需要删除学生的虚机
         * 4. 解除助教信息
         * 5. 删除默认班级
         */

        // 课程是否考试
        List<com.xlh.dto.courseTest.CourseClassDTO> testingData = paperService.getCourseClassPaper(
                Lists.newArrayList(new com.xlh.dto.courseTest.CourseClassDTO(courseId, classId)));
        if (errorFlag == null && CollectionUtils.isNotEmpty(testingData)) {
            throw new DeleteDealOperatingException("当前课程正在考试");
        }

        // 关闭签到
        List<Long> teacherIds = courseService.getCourseTeacherIds(courseId, classId);
        if (CollectionUtils.isNotEmpty(teacherIds)) {
            for (Long teacherId : teacherIds) {
                attendanceService.endRecord(teacherId, courseId, Lists.newArrayList(classId));
            }
        }

        // 当前课程下的任务id集合
        List<ChapterBasicInfoDTO> chapters = chapterService.listChapter(
                Lists.newArrayList(courseId), null, null, ChapterEnum.TASK);

        // 获取当前班级下的学生
        List<UserInfoDTO> userInfoDTOS = userService.queryClassUser(null, Lists.newArrayList(classId),
                Lists.newArrayList(UserStatusEnum.NOT_DELETE.getCode(), UserStatusEnum.ACCOUNT_CANCELLATION.getCode()),
                false);

        // 改变课程与班级的状态
        updateClassCourse(courseId, classId);

        // 删除学生的虚机
        if (CollectionUtils.isNotEmpty(userInfoDTOS) && CollectionUtils.isNotEmpty(chapters)) {
            containerService.deleteContainerByContext(ContextTypeEnum.TASK.getCode(),
                    chapters.stream().map(ChapterBasicInfoDTO::getId).collect(Collectors.toList()),
                    userInfoDTOS.stream().map(UserInfoDTO::getId).collect(Collectors.toList()));
        }

        // 解除助教信息
        courseService.deleteCourseTeachers(courseId, Lists.newArrayList(classId));

        // 删除默认班级
        deleteDefaultClass(courseId, classId);

    }

    private void updateClassCourse(Long courseId, Long classId) {
        ClassCourse classCourse = new ClassCourse();
        classCourse.setEnded(true);

        ClassCourseExample example = new ClassCourseExample();
        example.createCriteria()
                .andClassIdEqualTo(classId).andCourseIdEqualTo(courseId)
                .andEndedEqualTo(false).andDeletedEqualTo(false);

        classCourseMapper.updateByExampleSelective(classCourse, example);
    }

    @Override
    public PageDTO<UserInfoDTO> listStudentByPage(Integer pageNum, Integer pageSize, Long classId, String userInfo) {
        PageHelper.startPage(pageNum, pageSize);
        List<UserInfoDTO> userInfoDTOS = userService.queryClassUser(Lists.newArrayList(classId), userInfo);
        PageInfo<UserInfoDTO> pageInfo = new PageInfo<>(userInfoDTOS);
        return new PageDTO<>(pageInfo);
    }

    @Override
    public String queryClassInfoFlag(Long classId) {
        String flag = classMapper.selectClassInfoFlag(classId);
        return flag;
    }

    @Override
    public List<ClassCourseDTO> queryClassCourse(List<Long> classIds) {
        return classCourseMapperExt.listClassCourse(null, null, null, null, classIds);
    }

    @Override
    public List<ClassCourseDTO> listClassCourse(
            List<Long> courseIds, Boolean ended, String grade, String name, List<Long> ids) {
        return classCourseMapperExt.listClassCourse(courseIds, ended, grade, name, ids);
    }

    @Override
    public List<Class> queryClass(List<Long> userIds) {
        ClassExample example = new ClassExample();
        example.createCriteria().andDeletedEqualTo(false).andUserIdIn(userIds);
        return classMapper.selectByExample(example);
    }

    @Override
    public List<Class> queryClassByIds(List<Long> classIds) {
        if (CollectionUtils.isEmpty(classIds)) return null;
        ClassExample example = new ClassExample();
        example.createCriteria().andDeletedEqualTo(false).andIdIn(classIds);
        return classMapper.selectByExample(example);
    }

    @Override
    public List<Long> queryStudentClass(Long courseId, Boolean endFlag) {

        if (!userInfoHolder.isStudent()) return null;

        // 获取这门课的班级集合
        List<ClassCourseDTO> classCourseDTOS = classService.listClassCourse(Lists.newArrayList(courseId), endFlag);
        if (CollectionUtils.isEmpty(classCourseDTOS)) return null;

        // 获取学生的班级id集合
        List<Long> studentClassIds = userInfoHolder.getStudentClassIds();
        if (CollectionUtils.isEmpty(studentClassIds)) return null;

        // 取两个集合的交集
        List<ClassCourseDTO> classList = classCourseDTOS.stream()
                .filter(classCourseDTO -> studentClassIds.contains(classCourseDTO.getId()))
                .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(classList)) {
            return classList.stream().map(ClassCourseDTO::getId).collect(Collectors.toList());
        }

        return null;
    }

    @Override
    public PageDTO<ClassInfoDTO> queryClassInfo(Integer pageNum, Integer pageSize, String grade, String classInfo) {
        Map<String, Object> map = new HashMap();
        PageHelper.startPage(pageNum, pageSize);
        map.put("grade", grade);
        map.put("classInfo", classInfo);
        List<ClassInfoDTO> listall = classMapper.selectClassInfo(map);
        List<ClassInfoDTO> list = BeanUtil.batchTransform(ClassInfoDTO.class, listall);

        // 获取当前班级的人数
        List<Long> classIds = list.stream().map(ClassInfoDTO::getId).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(classIds)) {
            Map<Long, Long> studentCountMap = userService.getCountByClassId(classIds);

            list.forEach(classInfoDTO -> {
                if (MapUtils.isNotEmpty(studentCountMap) && studentCountMap.get(classInfoDTO.getId()) != null) {
                    classInfoDTO.setStudentNum(studentCountMap.get(classInfoDTO.getId()));
                }
            });
        }
        PageInfo<ClassInfoDTO> pageInfo = new PageInfo<>(listall);
        pageInfo.setList(list);
        return new PageDTO<>(pageInfo);
    }

    @Override
    public List<String> queryNaturalClassInfo() {
        List<String> list = classMapper.selectNaClassInfo();
        return list;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveClassInfo(ClassCourseParam params) {

        checkClass(params.getName(), Integer.valueOf(params.getGrade()), null);
        Class classinfo = new Class();
        classinfo.setName(params.getName());
        classinfo.setGrade(params.getGrade());
        classinfo.setCreateTime(new Date());
        classinfo.setDeleted(false);
        classMapper.insert(classinfo);
    }

    private void deleteClassCourse(Long courseId, List<Long> classIds, Boolean logicDeleted) {
        ClassCourseExample example = new ClassCourseExample();
        ClassCourseExample.Criteria criteria = example.createCriteria();
        criteria.andDeletedEqualTo(false);
        if (CollectionUtils.isNotEmpty(classIds)) {
            criteria.andClassIdIn(classIds);
        }
        if (courseId != null) {
            criteria.andCourseIdEqualTo(courseId);
        }

        if (!logicDeleted) {
            classCourseMapper.deleteByExample(example);
            return;
        }

        ClassCourse classCourse = new ClassCourse();
        classCourse.setDeleted(true);
        classCourseMapper.updateByExampleSelective(classCourse, example);
    }

    private void deleteClass(List<Long> classIds, Boolean logicDeleted) {
        if (CollectionUtils.isEmpty(classIds)) return;
        ClassExample example = new ClassExample();
        example.createCriteria().andIdIn(classIds).andDeletedEqualTo(false);

        if (!logicDeleted) {
            classMapper.deleteByExample(example);
            return;
        }

        Class dbClass = new Class();
        dbClass.setDeleted(true);
        classMapper.updateByExampleSelective(dbClass, example);
    }

    private Class checkAndGetClass(Long classId, String name) {
        Class dbClass = classMapper.selectByPrimaryKey(classId);
        if (dbClass == null || dbClass.getDeleted()) {
            throw new BadRequestException("班级不存在");
        }

        // 检查班级名称是否重复
        checkClassNameIsExist(name, classId, userInfoHolder.getUserId());
        return dbClass;
    }

    private Class convertClass(String name, Integer grade, Long userId) {
        Class dbClass = new Class();
        dbClass.setName(name);
        dbClass.setUserId(userId);
        dbClass.setGrade(String.valueOf(grade));
        return dbClass;
    }

    private void checkClass(String name, Integer grade, Long userId) {
        // 班级名称、年级需要必填
        if (StringUtils.isBlank(name) || grade == null) {
            throw new BadRequestException("班级名称不能为空");
        }
        // 检查班级、年级长度
        if (name.length() > 20) {
            throw new BadRequestException("班级名称不能超过20个字符");
        }
        if (String.valueOf(grade).length() != 4) {
            throw new BadRequestException("年级不能超过4个字符");
        }

        // 检查班级名称是否重复
        checkClassNameIsExist(name, null, userId);
    }

    private List<Long> checkAndGetUserIds(List<Long> courseIds, String name, Integer grade,
                                          Long studentClassId, List<CreateUserParam> createUserParams,
                                          Boolean errorFlag, Long userId, List<Long> studentIds) {
        // 检查班级
        checkClass(name, grade, userId);

        // 检查导入学生的信息 并插入
        return checkAndGetUserId(courseIds, studentClassId, createUserParams, errorFlag, studentIds);
    }

    private List<Long> checkAndGetUserId(
            List<Long> courseIds, Long studentClassId, List<CreateUserParam> createUserParams, Boolean errorFlag, List<Long> studentIds) {
        List<Long> userIds = null;
        if (studentClassId != null) {
            List<UserClass> userClasses = userService.listUserClass(studentClassId);
            if (CollectionUtils.isNotEmpty(userClasses)) {
                userIds = userClasses.stream().map(UserClass::getUserId).collect(Collectors.toList());
            }
        } else {
            if (studentIds != null && studentIds.size() > 0) {
                userIds = studentIds;
                List<UserInfoDTO> userInfoDTOS = userService.queryUserInfos(userIds,
                        Lists.newArrayList(UserStatusEnum.NOT_DELETE));
                if (CollectionUtils.isEmpty(userInfoDTOS)) {
                    throw new BadRequestException("当前班级暂无学生信息");
                }
                createUserParams = BeanUtil.batchTransform(CreateUserParam.class, userInfoDTOS);
                createUserParams.forEach(param -> param.setPassword(UserConstant.INIT_PASSWORD));
            }
        }
        if (CollectionUtils.isNotEmpty(createUserParams)) {
            return userService.createUser(createUserParams, IdentityEnum.STUDENT, courseIds, null, errorFlag);
        }
        return null;
    }

    private void checkClassNameIsExist(String name, Long id, Long userId) {
        List<Class> classList = classMapperExt.queryClassNameExist(name, id, userId);
        if (CollectionUtils.isNotEmpty(classList)) {
            throw new BadRequestException("班级名称已存在");
        }
    }

    private List<ClassDTO> getClassList(Long courseId, Boolean endFlag, String grade, String name) {
        List<ClassCourseDTO> classes = classCourseMapperExt.listClassCourse(
                Lists.newArrayList(courseId), endFlag, grade, name, null);
        return BeanUtil.batchTransform(ClassDTO.class, classes).stream()
                .distinct().collect(Collectors.toList());
    }

    private List<UserClassDTO> convertUserClass(List<UserClassDTO> userClassDTOS) {
        userClassDTOS.forEach(userClassDTO -> {
            userClassDTO.setStudentNum(userClassDTO.getUsers().stream().count());
            userClassDTO.setUsers(
                    userClassDTO.getUsers().stream().limit(10).collect(Collectors.toList())
            );
        });
        return userClassDTOS;
    }

    private List<ClassInfoDTO> convertClass(List<ClassCourseDTO> data) {

        if (CollectionUtils.isEmpty(data)) {
            return Lists.newArrayList();
        }

        List<ClassInfoDTO> list = BeanUtil.batchTransform(ClassInfoDTO.class, data);

        // 获取当前班级的人数
        List<Long> classIds = list.stream().map(ClassInfoDTO::getId).collect(Collectors.toList());
        Map<Long, Long> studentCountMap = userService.getCountByClassId(classIds);

        list.forEach(classInfoDTO -> {
            if (MapUtils.isNotEmpty(studentCountMap) && studentCountMap.get(classInfoDTO.getId()) != null) {
                classInfoDTO.setStudentNum(studentCountMap.get(classInfoDTO.getId()));
            }
        });

        return list;
    }

    private void insertClassCourse(Long classId, List<Long> courseIds) {
        classCourseMapperExt.insertBatch(courseIds, classId);
    }

    private List<Long> copyCourse(List<CourseDTO> courseDTOS, Long userId) {

        List<Long> newCourseIds = Lists.newArrayList();
        for (CourseDTO courseDTO : courseDTOS) {

            Long dbCourseId = courseService.queryExistCourseId(courseDTO.getCourseBasicId(), userId);
            if (dbCourseId != null) {
                newCourseIds.add(dbCourseId);
                continue;
            }

            Long newCourseId = courseService.createCourse(courseDTO.getId(), userId);

            // 拷贝课程额外信息
            directionService.copyCourseExtend(courseDTO.getId(), newCourseId);

            // 获取拷贝前课程id的章节id集合
            List<ChapterBasicInfoDTO> chapters = chapterService.listChapter(
                    Lists.newArrayList(courseDTO.getId()), null, null, ChapterEnum.CHAPTER);

            // 拷贝章节
            Map<Long, Long> chapterMap = null;
            if (CollectionUtils.isNotEmpty(chapters)) {
                chapterMap = chapterService.importExistChapter(courseDTO.getId(), newCourseId,
                        chapters.stream().map(ChapterBasicInfoDTO::getId).collect(Collectors.toList()));
            }

            // 拷贝课程下无章节的考试题库
            questionRepositoryService.copyRepository(courseDTO.getId(), null, null,
                    newCourseId, userId, true);

            // 拷贝课程分类
            copyCourseSort(courseDTO.getId(), newCourseId, chapterMap);

            // 拷贝课程资源
            copyCourseResource(courseDTO.getId(), newCourseId);

            newCourseIds.add(newCourseId);
        }

        return newCourseIds;
    }

    private void copyCourseResource(Long oldCourseId, Long newCourseId) {

        // 获取课程的资源
        ResourceRelationTypeEnum typeEnum = ResourceRelationTypeEnum.COURSE;
        List<ResourceRelationDTO> resource = resourceService.getResourceRelationInfo(
                Lists.newArrayList(oldCourseId), Lists.newArrayList(ResourcesTypeEnum.COURSE_OUTLINE.getCode()),
                null, typeEnum.getCode());
        if (CollectionUtils.isEmpty(resource)) return;

        // 添加到数据库
        resourceService.insertBatchResourceRelation(convertResourceRelation(newCourseId, resource, typeEnum));

    }

    private List<ResourceRelation> convertResourceRelation(
            Long courseId, List<ResourceRelationDTO> resource, ResourceRelationTypeEnum typeEnum) {
        List<ResourceRelation> data = Lists.newArrayList();
        resource.forEach(resourceRelationDTO -> {
            ResourceRelation resourceRelation = new ResourceRelation();
            resourceRelation.setObjId(courseId);
            resourceRelation.setResourceId(resourceRelationDTO.getResourceId());
            resourceRelation.setType(typeEnum.getCode());
            data.add(resourceRelation);
        });
        return data;
    }

    private void copyCourseSort(Long oldCourseId, Long newCourseId, Map<Long, Long> chapterMap) {
        List<CourseSort> courseSorts = courseService.queryCourseSort(Lists.newArrayList(oldCourseId));
        if (CollectionUtils.isEmpty(courseSorts)) return;

        List<ChapterCourseSort> chapterCourseSorts = chapterService.queryChapterCourseSort(
                courseSorts.stream().map(CourseSort::getId).collect(Collectors.toList()), null);

        // 拷贝课程分类
        courseService.createOrUpdateCourseSort(newCourseId, convertSortParam(courseSorts));

        // 获取课程分类Map<原始分类id,新增的分类id>
        List<CourseSort> newCourseSorts = courseService.queryCourseSort(Lists.newArrayList(newCourseId));
        Map<Long, Long> courseSortMap = Maps.newHashMap();
        for (int i = 0; i < courseSorts.size(); i++) {
            courseSortMap.put(courseSorts.get(i).getId(), newCourseSorts.get(i).getId());
        }

        // 拷贝章节-课程分类
        chapterService.createOrUpdateChapterCourseSort(
                newCourseId, convertChapterSortParam(courseSortMap, chapterCourseSorts, chapterMap));

    }

    private List<CreateChapterCourseSortParam> convertChapterSortParam(
            Map<Long, Long> courseSortMap, List<ChapterCourseSort> chapterCourseSorts, Map<Long, Long> chapterMap) {
        List<CreateChapterCourseSortParam> params = Lists.newArrayList();
        courseSortMap.forEach((oldCourseSortId, newCourseSortId) -> {
            List<ChapterCourseSort> chapterCourseSortList = chapterCourseSorts.stream()
                    .filter(chapterCourseSort -> Objects.equals(oldCourseSortId, chapterCourseSort.getCourseSortId()))
                    .map(chapterCourseSort -> {
                        chapterCourseSort.setChapterId(chapterMap.get(chapterCourseSort.getChapterId()));
                        return chapterCourseSort;
                    })
                    .collect(Collectors.toList());
            CreateChapterCourseSortParam param = new CreateChapterCourseSortParam();
            param.setId(newCourseSortId);
            param.setChapterIds(
                    chapterCourseSortList.stream().map(ChapterCourseSort::getChapterId).collect(Collectors.toList()));
            params.add(param);

        });
        return params;
    }

    private List<CreateOrUpdateCourseSortParam> convertSortParam(List<CourseSort> courseSorts) {
        List<CreateOrUpdateCourseSortParam> params = Lists.newArrayList();
        courseSorts.forEach(courseSort -> {
            CreateOrUpdateCourseSortParam param = new CreateOrUpdateCourseSortParam();
            param.setId(0L);
            param.setName(courseSort.getName());
            params.add(param);
        });

        return params;
    }

    private List<ClassZtreeDTO> convertZtreeDTO(List<ClassDTO> classDTOS, Boolean allFlag, Boolean defaultClassFlag) {

        List<ClassZtreeDTO> classZtreeDTOS = BeanUtil.batchTransform(ClassZtreeDTO.class, classDTOS);
        Map<Boolean, List<ClassZtreeDTO>> endedMap = BeanUtil.aggByKeyToList("ended", classZtreeDTOS);
        List<ClassZtreeDTO> result = Lists.newArrayList();

        // 设置结课
        if (allFlag && MapUtils.isNotEmpty(endedMap)) {
            result.add(convertZtree("全部", null,
                    classZtreeDTOS.stream().map(ClassZtreeDTO::getId).collect(Collectors.toList()),
                    defaultClassFlag));
        }
        endedMap.forEach((ended, classZtreeData) -> {
            ClassZtreeDTO ztreeDTO = convertZtree(
                    ended ? ClassStatusEnum.ENDED.getMessage() : ClassStatusEnum.UNFINISHED.getMessage(),
                    classZtreeData, classZtreeData.stream().map(ClassZtreeDTO::getId).collect(Collectors.toList()),
                    defaultClassFlag);

            // 设置年级
            List<ClassZtreeDTO> gradeZtreeData = Lists.newArrayList();
            Map<String, List<ClassZtreeDTO>> gradeMap = BeanUtil.aggByKeyToList("grade", classZtreeData);
            if (allFlag && MapUtils.isNotEmpty(gradeMap)) {
                gradeZtreeData.add(convertZtree("全部", null,
                        classZtreeData.stream().map(ClassZtreeDTO::getId).collect(Collectors.toList()),
                        defaultClassFlag));
            }
            gradeMap.forEach((grade, classDTOS1) -> {
                ClassZtreeDTO gradeZtree = convertZtree(grade, classDTOS1,
                        classDTOS1.stream().map(ClassZtreeDTO::getId).collect(Collectors.toList()),
                        defaultClassFlag);

                // 设置班级名称
                List<ClassZtreeDTO> classNameZtreeData = Lists.newArrayList();
                Map<String, List<ClassZtreeDTO>> nameMap = BeanUtil.aggByKeyToList("name", classDTOS1);
                if (allFlag && MapUtils.isNotEmpty(nameMap)) {
                    classNameZtreeData.add(convertZtree("全部", null,
                            classDTOS1.stream().map(ClassZtreeDTO::getId).collect(Collectors.toList()),
                            defaultClassFlag));
                }
                nameMap.forEach((className, classDTOS2) -> {
                    if (!defaultClassFlag) {
                        classDTOS2.forEach(classZtreeDTO -> {
                            classZtreeDTO.setDefaultedClass(false);
                        });
                    }
                    classNameZtreeData.addAll(classDTOS2);
                });

                gradeZtree.setChildren(classNameZtreeData);
                gradeZtreeData.add(gradeZtree);
            });

            ztreeDTO.setChildren(gradeZtreeData);
            result.add(ztreeDTO);
        });
        return result;
    }

    private ClassZtreeDTO convertZtree(String name, List<ClassZtreeDTO> classZtreeData,
                                       List<Long> classIds, Boolean defaultClassFlag) {
        ClassZtreeDTO ztreeDTO = new ClassZtreeDTO();
        ztreeDTO.setName(name);
        if (CollectionUtils.isNotEmpty(classZtreeData)
                && classZtreeData.stream().filter(classZtreeDTO -> classZtreeDTO.getDefaultedClass()).count() > 0) {
            ztreeDTO.setDefaultedClass(true);
        }
        if (CollectionUtils.isNotEmpty(classIds)) {
            ztreeDTO.setClassIds(classIds);
        }
        if (!defaultClassFlag) {
            ztreeDTO.setDefaultedClass(false);
        }
        return ztreeDTO;
    }

    private List<Long> checkAndGetClassIds(Long courseId, List<Long> classIds, Boolean errorFlag) {

        if (CollectionUtils.isEmpty(classIds)) throw new BadRequestException("请选择需要删除的班级");

        // 获取课程下的班级
        List<ClassCourse> classCourses = classService.listClassCourse(courseId, false);
        if (CollectionUtils.isEmpty(classCourses)
                || !CollectionUtils.containsAny(classIds,
                classCourses.stream().map(ClassCourse::getClassId).collect(Collectors.toList()))) {
            throw new BadRequestException("请选择正确班级");
        }

        // 课程是否考试
        List<com.xlh.dto.courseTest.CourseClassDTO> list = Lists.newArrayList();
        classIds.forEach(classId -> {
            list.add(new com.xlh.dto.courseTest.CourseClassDTO(courseId, classId));
        });
        List<com.xlh.dto.courseTest.CourseClassDTO> testingData = paperService.getCourseClassPaper(list);

        // 获取课程下的学生数据
        List<CourseClassDTO> courseClassDTOS = classService.queryUserClass(Lists.newArrayList(courseId));

        // 如果无报错处理并且 教师被占用 或者 有学生数据，就提示错误信息
        if (errorFlag == null
                && (CollectionUtils.isNotEmpty(courseClassDTOS) || CollectionUtils.isNotEmpty(testingData))) {
            List<String> errorList = Lists.newArrayList();
            if (CollectionUtils.isNotEmpty(courseClassDTOS)) {
                errorList.add("学生及学习记录将被删除");
            }
            if (CollectionUtils.isNotEmpty(testingData)) {
                errorList.add("该课程正在考试");
            }
            throw new DeleteDealOperatingException("班级中" + StringUtils.join(errorList, "且"));
        }

        return classCourses.stream()
                .filter(classDTO -> classIds.contains(classDTO.getClassId()))
                .map(ClassCourse::getClassId).collect(Collectors.toList());

    }

}
